package com.google.typography.font.sfntly.table.opentype.testing;

import com.google.typography.font.sfntly.Font;
import com.google.typography.font.sfntly.Tag;
import com.google.typography.font.sfntly.table.opentype.GSubTable;
import com.google.typography.font.sfntly.table.opentype.ScriptListTable;
import com.google.typography.font.sfntly.table.opentype.ScriptTag;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

class FontLanguages {
  private static String[][] langScriptData = { { "aa", "Latn" },
    { "ab", "Cyrl" },
    { "abq", "Cyrl" },
    { "ace", "Latn" },
    { "ach", "Latn" },
    { "ada", "Latn" },
    { "ady", "Cyrl" },
    { "ae", "Avst" },
    { "af", "Latn" },
    { "agq", "Latn" },
    { "aii", "Cyrl" },
    { "aii", "Syrc" },
    { "ain", "Kana", "Latn" },
    { "ak", "Latn" },
    { "akk", "Xsux" },
    { "ale", "Latn" },
    { "alt", "Cyrl" },
    { "am", "Ethi" },
    { "amo", "Latn" },
    { "an", "Latn" },
    { "anp", "Deva" },
    { "ar", "Arab" },
    { "ar", "Syrc" },
    { "arc", "Armi" },
    { "arn", "Latn" },
    { "arp", "Latn" },
    { "arw", "Latn" },
    { "as", "Beng" },
    { "asa", "Latn" },
    { "ast", "Latn" },
    { "av", "Cyrl" },
    { "awa", "Deva" },
    { "ay", "Latn" },
    { "az", "Arab", "Cyrl", "Latn" },
    { "ba", "Cyrl" },
    { "bal", "Arab", "Latn" },
    { "ban", "Latn" },
    { "ban", "Bali" },
    { "bas", "Latn" },
    { "bax", "Bamu" },
    { "bbc", "Latn" },
    { "bbc", "Batk" },
    { "be", "Cyrl" },
    { "bej", "Arab" },
    { "bem", "Latn" },
    { "bez", "Latn" },
    { "bfq", "Taml" },
    { "bft", "Arab" },
    { "bft", "Tibt" },
    { "bfy", "Deva" },
    { "bg", "Cyrl" },
    { "bh", "Deva", "Kthi" },
    { "bhb", "Deva" },
    { "bho", "Deva" },
    { "bi", "Latn" },
    { "bik", "Latn" },
    { "bin", "Latn" },
    { "bjj", "Deva" },
    { "bku", "Latn" },
    { "bku", "Buhd" },
    { "bla", "Latn" },
    { "blt", "Tavt" },
    { "bm", "Latn" },
    { "bn", "Beng" },
    { "bo", "Tibt" },
    { "bqv", "Latn" },
    { "br", "Latn" },
    { "bra", "Deva" },
    { "brx", "Deva" },
    { "bs", "Latn" },
    { "btv", "Deva" },
    { "bua", "Cyrl" },
    { "buc", "Latn" },
    { "bug", "Latn" },
    { "bug", "Bugi" },
    { "bya", "Latn" },
    { "byn", "Ethi" },
    { "ca", "Latn" },
    { "cad", "Latn" },
    { "car", "Latn" },
    { "cay", "Latn" },
    { "cch", "Latn" },
    { "ccp", "Beng" },
    { "ccp", "Cakm" },
    { "ce", "Cyrl" },
    { "ceb", "Latn" },
    { "cgg", "Latn" },
    { "ch", "Latn" },
    { "chk", "Latn" },
    { "chm", "Cyrl", "Latn" },
    { "chn", "Latn" },
    { "cho", "Latn" },
    { "chp", "Latn" },
    { "chp", "Cans" },
    { "chr", "Cher", "Latn" },
    { "chy", "Latn" },
    { "cja", "Arab" },
    { "cja", "Cham" },
    { "cjm", "Cham" },
    { "cjm", "Arab" },
    { "cjs", "Cyrl" },
    { "ckb", "Arab" },
    { "ckt", "Cyrl" },
    { "co", "Latn" },
    { "cop", "Arab", "Copt", "Grek" },
    { "cpe", "Latn" },
    { "cr", "Cans", "Latn" },
    { "crh", "Cyrl" },
    { "crk", "Cans" },
    { "cs", "Latn" },
    { "csb", "Latn" },
    { "cu", "Glag" },
    { "cv", "Cyrl" },
    { "cy", "Latn" },
    { "da", "Latn" },
    { "dak", "Latn" },
    { "dar", "Cyrl" },
    { "dav", "Latn" },
    { "de", "Latn" },
    { "de", "Runr" },
    { "del", "Latn" },
    { "den", "Latn" },
    { "den", "Cans" },
    { "dgr", "Latn" },
    { "din", "Latn" },
    { "dje", "Latn" },
    { "dng", "Cyrl" },
    { "doi", "Arab" },
    { "dsb", "Latn" },
    { "dua", "Latn" },
    { "dv", "Thaa" },
    { "dyo", "Arab" },
    { "dyo", "Latn" },
    { "dyu", "Latn" },
    { "dz", "Tibt" },
    { "ebu", "Latn" },
    { "ee", "Latn" },
    { "efi", "Latn" },
    { "egy", "Egyp" },
    { "eka", "Latn" },
    { "eky", "Kali" },
    { "el", "Grek" },
    { "en", "Latn" },
    { "en", "Dsrt", "Shaw" },
    { "eo", "Latn" },
    { "es", "Latn" },
    { "et", "Latn" },
    { "ett", "Ital", "Latn" },
    { "eu", "Latn" },
    { "evn", "Cyrl" },
    { "ewo", "Latn" },
    { "fa", "Arab" },
    { "fan", "Latn" },
    { "ff", "Latn" },
    { "fi", "Latn" },
    { "fil", "Latn" },
    { "fil", "Tglg" },
    { "fiu", "Latn" },
    { "fj", "Latn" },
    { "fo", "Latn" },
    { "fon", "Latn" },
    { "fr", "Latn" },
    { "frr", "Latn" },
    { "frs", "Latn" },
    { "fur", "Latn" },
    { "fy", "Latn" },
    { "ga", "Latn" },
    { "gaa", "Latn" },
    { "gag", "Latn" },
    { "gag", "Cyrl" },
    { "gay", "Latn" },
    { "gba", "Arab" },
    { "gbm", "Deva" },
    { "gcr", "Latn" },
    { "gd", "Latn" },
    { "gez", "Ethi" },
    { "gil", "Latn" },
    { "gl", "Latn" },
    { "gld", "Cyrl" },
    { "gn", "Latn" },
    { "gon", "Deva", "Telu" },
    { "gor", "Latn" },
    { "got", "Goth" },
    { "grb", "Latn" },
    { "grc", "Cprt", "Grek", "Linb" },
    { "grt", "Beng" },
    { "gsw", "Latn" },
    { "gu", "Gujr" },
    { "guz", "Latn" },
    { "gv", "Latn" },
    { "gwi", "Latn" },
    { "ha", "Arab", "Latn" },
    { "hai", "Latn" },
    { "haw", "Latn" },
    { "he", "Hebr" },
    { "hi", "Deva" },
    { "hil", "Latn" },
    { "hit", "Xsux" },
    { "hmn", "Latn" },
    { "hne", "Deva" },
    { "hnn", "Latn" },
    { "hnn", "Hano" },
    { "ho", "Latn" },
    { "hoc", "Deva" },
    { "hoj", "Deva" },
    { "hop", "Latn" },
    { "hr", "Latn" },
    { "hsb", "Latn" },
    { "ht", "Latn" },
    { "hu", "Latn" },
    { "hup", "Latn" },
    { "hy", "Armn" },
    { "hz", "Latn" },
    { "ia", "Latn" },
    { "iba", "Latn" },
    { "ibb", "Latn" },
    { "id", "Latn" },
    { "id", "Arab" },
    { "ig", "Latn" },
    { "ii", "Yiii" },
    { "ii", "Latn" },
    { "ik", "Latn" },
    { "ilo", "Latn" },
    { "inh", "Cyrl" },
    { "inh", "Arab", "Latn" },
    { "is", "Latn" },
    { "it", "Latn" },
    { "iu", "Cans" },
    { "iu", "Latn" },
    { "ja", "Jpan" },
    { "jmc", "Latn" },
    { "jpr", "Hebr" },
    { "jrb", "Hebr" },
    { "jv", "Latn" },
    { "jv", "Java" },
    { "ka", "Geor" },
    { "kaa", "Cyrl" },
    { "kab", "Latn" },
    { "kac", "Latn" },
    { "kaj", "Latn" },
    { "kam", "Latn" },
    { "kbd", "Cyrl" },
    { "kca", "Cyrl" },
    { "kcg", "Latn" },
    { "kde", "Latn" },
    { "kdt", "Thai" },
    { "kea", "Latn" },
    { "kfo", "Latn" },
    { "kfr", "Deva" },
    { "kg", "Latn" },
    { "kha", "Latn" },
    { "kha", "Beng" },
    { "khb", "Talu" },
    { "khq", "Latn" },
    { "kht", "Mymr" },
    { "ki", "Latn" },
    { "kj", "Latn" },
    { "kjh", "Cyrl" },
    { "kk", "Cyrl" },
    { "kk", "Arab" },
    { "kl", "Latn" },
    { "kln", "Latn" },
    { "km", "Khmr" },
    { "kmb", "Latn" },
    { "kn", "Knda" },
    { "ko", "Hang", "Kore" },
    { "koi", "Cyrl" },
    { "kok", "Deva" },
    { "kos", "Latn" },
    { "kpe", "Latn" },
    { "kpy", "Cyrl" },
    { "kr", "Latn" },
    { "krc", "Cyrl" },
    { "kri", "Latn" },
    { "krl", "Cyrl", "Latn" },
    { "kru", "Deva" },
    { "ks", "Arab", "Deva" },
    { "ksb", "Latn" },
    { "ksf", "Latn" },
    { "ksh", "Latn" },
    { "ku", "Arab", "Cyrl", "Latn" },
    { "kum", "Cyrl" },
    { "kut", "Latn" },
    { "kv", "Cyrl", "Latn" },
    { "kw", "Latn" },
    { "ky", "Arab", "Cyrl" },
    { "ky", "Latn" },
    { "kyu", "Kali" },
    { "la", "Latn" },
    { "lad", "Hebr" },
    { "lag", "Latn" },
    { "lah", "Arab" },
    { "lam", "Latn" },
    { "lb", "Latn" },
    { "lbe", "Cyrl" },
    { "lcp", "Thai" },
    { "lep", "Lepc" },
    { "lez", "Cyrl" },
    { "lg", "Latn" },
    { "li", "Latn" },
    { "lif", "Deva", "Limb" },
    { "lis", "Lisu" },
    { "lki", "Arab" },
    { "lmn", "Telu" },
    { "ln", "Latn" },
    { "lo", "Laoo" },
    { "lol", "Latn" },
    { "loz", "Latn" },
    { "lt", "Latn" },
    { "lu", "Latn" },
    { "lua", "Latn" },
    { "lui", "Latn" },
    { "lun", "Latn" },
    { "luo", "Latn" },
    { "lus", "Beng" },
    { "lut", "Latn" },
    { "luy", "Latn" },
    { "lv", "Latn" },
    { "lwl", "Thai" },
    { "mad", "Latn" },
    { "mag", "Deva" },
    { "mai", "Deva" },
    { "mak", "Latn" },
    { "mak", "Bugi" },
    { "man", "Latn", "Nkoo" },
    { "mas", "Latn" },
    { "mdf", "Cyrl" },
    { "mdh", "Latn" },
    { "mdr", "Latn" },
    { "mdr", "Bugi" },
    { "men", "Latn" },
    { "mer", "Latn" },
    { "mfe", "Latn" },
    { "mg", "Latn" },
    { "mgh", "Latn" },
    { "mh", "Latn" },
    { "mi", "Latn" },
    { "mic", "Latn" },
    { "min", "Latn" },
    { "mk", "Cyrl" },
    { "ml", "Mlym" },
    { "mn", "Cyrl", "Mong" },
    { "mn", "Phag" },
    { "mnc", "Mong" },
    { "mni", "Beng" },
    { "mni", "Mtei" },
    { "mnk", "Latn" },
    { "mns", "Cyrl" },
    { "mnw", "Mymr" },
    { "moh", "Latn" },
    { "mos", "Latn" },
    { "mr", "Deva" },
    { "ms", "Latn" },
    { "ms", "Arab" },
    { "mt", "Latn" },
    { "mua", "Latn" },
    { "mus", "Latn" },
    { "mwl", "Latn" },
    { "mwr", "Deva" },
    { "my", "Mymr" },
    { "myv", "Cyrl" },
    { "myz", "Mand" },
    { "na", "Latn" },
    { "nap", "Latn" },
    { "naq", "Latn" },
    { "nb", "Latn" },
    { "nd", "Latn" },
    { "nds", "Latn" },
    { "ne", "Deva" },
    { "new", "Deva" },
    { "ng", "Latn" },
    { "nia", "Latn" },
    { "niu", "Latn" },
    { "nl", "Latn" },
    { "nmg", "Latn" },
    { "nn", "Latn" },
    { "nod", "Lana" },
    { "nog", "Cyrl" },
    { "nqo", "Nkoo" },
    { "nr", "Latn" },
    { "nso", "Latn" },
    { "nus", "Latn" },
    { "nv", "Latn" },
    { "ny", "Latn" },
    { "nym", "Latn" },
    { "nyn", "Latn" },
    { "nyo", "Latn" },
    { "nzi", "Latn" },
    { "oc", "Latn" },
    { "oj", "Cans" },
    { "oj", "Latn" },
    { "om", "Latn" },
    { "om", "Ethi" },
    { "or", "Orya" },
    { "os", "Cyrl", "Latn" },
    { "osa", "Latn" },
    { "osc", "Ital", "Latn" },
    { "otk", "Orkh" },
    { "pa", "Guru" },
    { "pa", "Arab" },
    { "pag", "Latn" },
    { "pal", "Phli" },
    { "pam", "Latn" },
    { "pap", "Latn" },
    { "pau", "Latn" },
    { "peo", "Xpeo" },
    { "phn", "Phnx" },
    { "pi", "Deva", "Sinh", "Thai" },
    { "pl", "Latn" },
    { "pon", "Latn" },
    { "pra", "Brah", "Khar" },
    { "prd", "Arab" },
    { "prg", "Latn" },
    { "prs", "Arab" },
    { "ps", "Arab" },
    { "pt", "Latn" },
    { "qu", "Latn" },
    { "raj", "Latn" },
    { "rap", "Latn" },
    { "rar", "Latn" },
    { "rcf", "Latn" },
    { "rej", "Latn" },
    { "rej", "Rjng" },
    { "rjs", "Deva" },
    { "rkt", "Beng" },
    { "rm", "Latn" },
    { "rn", "Latn" },
    { "ro", "Latn" },
    { "ro", "Cyrl" },
    { "rof", "Latn" },
    { "rom", "Cyrl", "Latn" },
    { "ru", "Cyrl" },
    { "rup", "Latn" },
    { "rw", "Latn" },
    { "rwk", "Latn" },
    { "sa", "Deva", "Sinh" },
    { "sad", "Latn" },
    { "saf", "Latn" },
    { "sah", "Cyrl" },
    { "sam", "Hebr", "Samr" },
    { "saq", "Latn" },
    { "sas", "Latn" },
    { "sat", "Latn" },
    { "sat", "Beng", "Deva", "Olck", "Orya" },
    { "saz", "Saur" },
    { "sbp", "Latn" },
    { "sc", "Latn" },
    { "scn", "Latn" },
    { "sco", "Latn" },
    { "sd", "Arab", "Deva" },
    { "sdh", "Arab" },
    { "se", "Latn" },
    { "se", "Cyrl" },
    { "see", "Latn" },
    { "seh", "Latn" },
    { "sel", "Cyrl" },
    { "ses", "Latn" },
    { "sg", "Latn" },
    { "sga", "Latn", "Ogam" },
    { "shi", "Arab" },
    { "shi", "Tfng" },
    { "shn", "Mymr" },
    { "si", "Sinh" },
    { "sid", "Latn" },
    { "sk", "Latn" },
    { "sl", "Latn" },
    { "sm", "Latn" },
    { "sma", "Latn" },
    { "smi", "Latn" },
    { "smj", "Latn" },
    { "smn", "Latn" },
    { "sms", "Latn" },
    { "sn", "Latn" },
    { "snk", "Latn" },
    { "so", "Latn" },
    { "so", "Arab", "Osma" },
    { "son", "Latn" },
    { "sq", "Latn" },
    { "sr", "Cyrl", "Latn" },
    { "srn", "Latn" },
    { "srr", "Latn" },
    { "ss", "Latn" },
    { "ssy", "Latn" },
    { "st", "Latn" },
    { "su", "Latn" },
    { "su", "Sund" },
    { "suk", "Latn" },
    { "sus", "Latn" },
    { "sus", "Arab" },
    { "sv", "Latn" },
    { "sw", "Latn" },
    { "swb", "Arab" },
    { "swb", "Latn" },
    { "swc", "Latn" },
    { "syl", "Beng" },
    { "syl", "Sylo" },
    { "syr", "Syrc" },
    { "ta", "Taml" },
    { "tab", "Cyrl" },
    { "tbw", "Latn" },
    { "tbw", "Tagb" },
    { "tcy", "Knda" },
    { "tdd", "Tale" },
    { "te", "Telu" },
    { "tem", "Latn" },
    { "teo", "Latn" },
    { "ter", "Latn" },
    { "tet", "Latn" },
    { "tg", "Arab", "Cyrl", "Latn" },
    { "th", "Thai" },
    { "ti", "Ethi" },
    { "tig", "Ethi" },
    { "tiv", "Latn" },
    { "tk", "Arab", "Cyrl", "Latn" },
    { "tkl", "Latn" },
    { "tli", "Latn" },
    { "tmh", "Latn" },
    { "tn", "Latn" },
    { "to", "Latn" },
    { "tog", "Latn" },
    { "tpi", "Latn" },
    { "tr", "Latn" },
    { "tr", "Arab" },
    { "tru", "Latn" },
    { "tru", "Syrc" },
    { "trv", "Latn" },
    { "ts", "Latn" },
    { "tsg", "Latn" },
    { "tsi", "Latn" },
    { "tt", "Cyrl" },
    { "tts", "Thai" },
    { "tum", "Latn" },
    { "tut", "Cyrl" },
    { "tvl", "Latn" },
    { "twq", "Latn" },
    { "ty", "Latn" },
    { "tyv", "Cyrl" },
    { "tzm", "Latn", "Tfng" },
    { "ude", "Cyrl" },
    { "udm", "Cyrl" },
    { "udm", "Latn" },
    { "ug", "Arab" },
    { "ug", "Cyrl", "Latn" },
    { "uga", "Ugar" },
    { "uk", "Cyrl" },
    { "uli", "Latn" },
    { "umb", "Latn" },
    { "unr", "Beng", "Deva" },
    { "unx", "Beng", "Deva" },
    { "ur", "Arab" },
    { "uz", "Arab", "Cyrl", "Latn" },
    { "vai", "Vaii" },
    { "ve", "Latn" },
    { "vi", "Latn" },
    { "vi", "Hani" },
    { "vo", "Latn" },
    { "vot", "Latn" },
    { "vun", "Latn" },
    { "wa", "Latn" },
    { "wae", "Latn" },
    { "wak", "Latn" },
    { "wal", "Ethi" },
    { "war", "Latn" },
    { "was", "Latn" },
    { "wo", "Latn" },
    { "wo", "Arab" },
    { "xal", "Cyrl" },
    { "xcr", "Cari" },
    { "xh", "Latn" },
    { "xog", "Latn" },
    { "xpr", "Prti" },
    { "xsa", "Sarb" },
    { "xsr", "Deva" },
    { "xum", "Ital", "Latn" },
    { "yao", "Latn" },
    { "yap", "Latn" },
    { "yav", "Latn" },
    { "yi", "Hebr" },
    { "yo", "Latn" },
    { "yrk", "Cyrl" },
    { "yue", "Hans" },
    { "za", "Latn" },
    { "za", "Hans" },
    { "zap", "Latn" },
    { "zen", "Tfng" },
    { "zh", "Hans", "Hant" },
    { "zh", "Bopo", "Phag" },
    { "zu", "Latn" },
    { "zun", "Latn" },
    { "zza", "Arab" }, };

  private static Map<String, ScriptTag> fontSpecificScript = new HashMap<String, ScriptTag>();
  private Map<ScriptTag, Set<String>> scriptLangMap = new HashMap<ScriptTag, Set<String>>();
  static {
    fontSpecificScript.put("laoo", ScriptTag.lao);
    fontSpecificScript.put("yiii", ScriptTag.yi);
    fontSpecificScript.put("jpan", ScriptTag.kana);
    fontSpecificScript.put("kore", ScriptTag.hang);
    fontSpecificScript.put("nkoo", ScriptTag.nko);
    fontSpecificScript.put("vaii", ScriptTag.vai);
    fontSpecificScript.put("hans", ScriptTag.hani);
    fontSpecificScript.put("hant", ScriptTag.hani);

  }

  FontLanguages(List<String> availableLangs) {
    for (String[] entry : langScriptData) {
      String lang = entry[0];
      if (!availableLangs.contains(lang)) {
        continue;
      }
      for (int i = 1; i < entry.length; i++) {
        String script = entry[i].toLowerCase();
        ScriptTag scriptTag = fontSpecificScript.containsKey(script) ? fontSpecificScript.get(
            script)
            : ScriptTag.valueOf(script);
            addLangScriptMap(lang, scriptTag);
      }
    }

    scriptLangMap.put(ScriptTag.DFLT, new HashSet<String>());
    scriptLangMap.put(ScriptTag.brai, new HashSet<String>());
    scriptLangMap.put(ScriptTag.math, new HashSet<String>());
    scriptLangMap.put(ScriptTag.musc, new HashSet<String>());
    scriptLangMap.put(ScriptTag.musi, new HashSet<String>());
    scriptLangMap.put(ScriptTag.mly2, scriptLangMap.get(ScriptTag.mlym));
    scriptLangMap.put(ScriptTag.mlm2, scriptLangMap.get(ScriptTag.mlym));
    scriptLangMap.put(ScriptTag.dev2, scriptLangMap.get(ScriptTag.deva));
    scriptLangMap.put(ScriptTag.mym2, scriptLangMap.get(ScriptTag.mymr));
    scriptLangMap.put(ScriptTag.tml2, scriptLangMap.get(ScriptTag.taml));
    scriptLangMap.put(ScriptTag.tel2, scriptLangMap.get(ScriptTag.telu));
    scriptLangMap.put(ScriptTag.knd2, scriptLangMap.get(ScriptTag.knda));
    scriptLangMap.put(ScriptTag.gur2, scriptLangMap.get(ScriptTag.guru));
    scriptLangMap.put(ScriptTag.gjr2, scriptLangMap.get(ScriptTag.gujr));
    scriptLangMap.put(ScriptTag.bng2, scriptLangMap.get(ScriptTag.beng));
    scriptLangMap.put(ScriptTag.ory2, scriptLangMap.get(ScriptTag.orya));
    scriptLangMap.put(ScriptTag.jamo, scriptLangMap.get(ScriptTag.hang));
  }

  private void addLangScriptMap(String lang, ScriptTag scriptTag) {
    if (!scriptLangMap.containsKey(scriptTag)) {
      scriptLangMap.put(scriptTag, new HashSet<String>());
    }
    Set<String> langs = scriptLangMap.get(scriptTag);
    langs.add(lang);
  }

  Set<String> get(Font font) {
    Set<String> langs = new HashSet<String>();
    GSubTable gsub = font.getTable(Tag.GSUB);
    if (gsub == null) {
      return langs;
    }

    ScriptListTable scriptList = gsub.scriptList();
    for (int i = 0; i < scriptList.count(); i++) {
      ScriptTag script = scriptList.scriptAt(i);
      if (scriptLangMap.containsKey(script)) {
        langs.addAll(scriptLangMap.get(script));
      } else {
        System.err.println("No language exists for the script: " + script);
      }
    }
    return langs;
  }
}
